package com.bd.scm.module.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bd.scm.domain.dto.query.ConditionDto;
import com.bd.utils.annotation.WhereType;
import com.bd.utils.enums.WhereTypeEnum;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * wrapper条件构造类
 */
@Data
public class WhereEntityUtil {
    private static Map<WhereTypeEnum, WhereFun> typeFunc;

    static {
        if (typeFunc == null) {
            typeFunc = new HashMap<>();
            typeFunc.put(WhereTypeEnum.EQ, (w, k, v) -> {
                w.eq(k, v);
            });
            typeFunc.put(WhereTypeEnum.NEQ, (w, k, v) -> {
                w.ne(k, v);
            });
            typeFunc.put(WhereTypeEnum.IN, (w, k, v) -> {
                if (v instanceof Collection) {
                    w.in(k, (Collection<?>) v);
                } else if (v instanceof Object[]) {
                    w.in(k, (Object[]) v);
                } else {
                    w.in(k, v.toString());
                }
            });
            typeFunc.put(WhereTypeEnum.LIKE, (w, k, v) -> {
                w.like(k, v.toString());
            });
            typeFunc.put(WhereTypeEnum.LE, (w, k, v) -> {
                w.le(k, v);
            });
            typeFunc.put(WhereTypeEnum.LT, (w, k, v) -> {
                w.lt(k, v);
            });
            typeFunc.put(WhereTypeEnum.GE, (w, k, v) -> {
                w.ge(k, v);
            });
            typeFunc.put(WhereTypeEnum.GT, (w, k, v) -> {
                w.gt(k, v);
            });
        }

    }

    /**
     * 封装成需要的wrapper
     *
     * @param t 实体对象
     * @return
     */
    public static <T> QueryWrapper invoke(Object t) {
        QueryWrapper<T> wrapper = new QueryWrapper();
        execute(t, wrapper);
        // 获取
        return wrapper;
    }

    public static void invoke(Object t, QueryWrapper wrapper) {
        execute(t, wrapper);
    }

    public static void execute(Object t, QueryWrapper wrapper) {
        //反射获取属性
        Field[] fields = t.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object val = field.get(t);
                String colum = "";
                if (val != null && !"".equals(val.toString())) {
                    WhereType whereType = field.getAnnotation(WhereType.class);
                    //没有注解，取默认为下划线拼接
                    if (whereType == null) {
                        colum = camelToUnderline(field.getName());
                        // 执行方法
                        typeFunc.get(WhereTypeEnum.EQ).whereFunc(wrapper, colum, val);

                    } else {
                        if (whereType.ignore()) {
                            continue;
                        } else {
                            //没有定义查询属性，取默认
                            if (!StringUtils.isBlank(whereType.filed())) {
                                colum = whereType.filed();
                            } else {
                                colum = camelToUnderline(field.getName());
                            }

                            // 执行方法
                            typeFunc.get(whereType.type()).whereFunc(wrapper, colum, val);
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public static QueryWrapper getWrapper(Object t) {
        QueryWrapper wrapper = new QueryWrapper();

        //反射获取属性
        Field[] fields = t.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object val = field.get(t);
                String colum = "";
                if (val != null && !"".equals(val.toString())) {
                    WhereType whereType = field.getAnnotation(WhereType.class);
                    //没有注解，取默认为下划线拼接
                    if (whereType == null) {
                        colum = camelToUnderline(field.getName());
                        // 执行方法
                        typeFunc.get(WhereTypeEnum.EQ).whereFunc(wrapper, colum, val);

                    } else {
                        if (whereType.ignore()) {
                            continue;
                        } else {
                            //没有定义查询属性，取默认
                            if (!StringUtils.isBlank(whereType.filed())) {
                                colum = whereType.filed();
                            } else {
                                colum = camelToUnderline(field.getName());
                            }

                            // 执行方法
                            typeFunc.get(whereType.type()).whereFunc(wrapper, colum, val);
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }
        return wrapper;
    }

    public static QueryWrapper getWrapper(List<ConditionDto> conditions) {
        QueryWrapper wrapper = new QueryWrapper();

        if (CollectionUtils.isEmpty(conditions)) return wrapper;

        conditions.forEach(col -> {
            String fieldName = camelToUnderline(col.getField());
            if(!StringUtils.isEmpty(col.getValue())){
                WhereTypeEnum logic = WhereTypeEnum.valueOf(col.getType().toUpperCase());
                if(logic == WhereTypeEnum.IN){
                    String[] split = StringUtils.split(col.getValue(), ",");
                    typeFunc.get(logic).whereFunc(wrapper, fieldName, split);
                }else{
                    typeFunc.get(logic).whereFunc(wrapper, fieldName, col.getValue());
                }
            }
        });

        return wrapper;
    }


    /**
     * 驼峰转下划线
     */
    public static String camelToUnderline(String param) {
        if (StringUtils.isEmpty(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append("_");
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

//    public static void main(String[] args) {
//        TestDto inStorePageVo = new TestDto();
//
//
//        QueryWrapper<TestDto> wrapper = WhereEntityUtil.invoke(inStorePageVo);
//        System.out.println(wrapper.toString());
//    }
}

